#pragma once
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cstddef>
#include <odb/core.hxx>
#include <odb/nullable.hxx>
#include <string>

namespace ken_im
{
#pragma db object table( "message" )
/**
 * @class Message
 * @brief 消息类，用于表示和操作消息对象。
 *
 * 该类用于表示一个消息对象，包含消息的基本信息，如消息ID、会话ID、用户ID、消息类型、创建时间等。
 * 支持文本消息、图片消息、文件消息和语音消息，每种消息类型都有相应的属性。
 *
 * @details
 * 该类使用ODB（Object Data Base）进行持久化存储，支持自动生成ID。
 *
 * @note
 * 该类中的所有属性都是可选的，除了消息ID和会话ID是必需的。
 *
 * @example
 * 创建一个文本消息对象：
 * @code
 * Message msg("msg123", "session456", "user789", 0,
 * boost::posix_time::second_clock::local_time());
 * msg.content("Hello, world!");
 * @endcode
 *
 * @param mid 消息ID
 * @param ssid 会话ID
 * @param uid 用户ID
 * @param mtype 消息类型（0-文本；1-图片；2-文件；3-语音）
 * @param ctime 消息创建时间
 */
class Message
{
  public:
    Message()
    {
    }
    Message( const std::string &mid, const std::string &ssid,
             const std::string &uid, const unsigned char mtype,
             const boost::posix_time::ptime &ctime )
        : _message_id( mid ), _session_id( ssid ), _user_id( uid ),
          _message_type( mtype ), _create_time( ctime )
    {
    }

    std::string message_id() const
    {
        return _message_id;
    }
    void message_id( const std::string &val )
    {
        _message_id = val;
    }

    std::string session_id() const
    {
        return _session_id;
    }
    void session_id( const std::string &val )
    {
        _session_id = val;
    }

    std::string user_id() const
    {
        return _user_id;
    }
    void user_id( const std::string &val )
    {
        _user_id = val;
    }

    unsigned char message_type() const
    {
        return _message_type;
    }
    void message_type( unsigned char val )
    {
        _message_type = val;
    }

    boost::posix_time::ptime create_time() const
    {
        return _create_time;
    }
    void create_time( const boost::posix_time::ptime &val )
    {
        _create_time = val;
    }

    std::string content() const
    {
        if ( !_content )
            return std::string();
        return *_content;
    }
    void content( const std::string &val )
    {
        _content = val;
    }

    std::string file_id() const
    {
        if ( !_file_id )
            return std::string();
        return *_file_id;
    }
    void file_id( const std::string &val )
    {
        _file_id = val;
    }

    std::string file_name() const
    {
        if ( !_file_name )
            return std::string();
        return *_file_name;
    }
    void file_name( const std::string &val )
    {
        _file_name = val;
    }

    unsigned int file_size() const
    {
        if ( !_file_size )
            return 0;
        return *_file_size;
    }
    void file_size( unsigned int val )
    {
        _file_size = val;
    }

  private:
    friend class odb::access;

#pragma db id auto
    unsigned long _id;

#pragma db type( "varchar(64)" ) index unique
    std::string _message_id;

#pragma db type( "varchar(64)" ) index
    std::string _session_id; // 所属会话ID

#pragma db type( "varchar(64)" )
    std::string _user_id; // 发送者用户ID

    unsigned char _message_type; // 消息类型 0-文本；1-图片；2-文件；3-语音

#pragma db type( "TIMESTAMP" )
    boost::posix_time::ptime _create_time; // 消息的产生时间

    odb::nullable<std::string> _content; // 文本消息内容--非文本消息可以忽略

#pragma db type( "varchar(64)" )
    odb::nullable<std::string> _file_id; // 文件消息的文件ID -- 文本消息忽略

#pragma db type( "varchar(128)" )
    odb::nullable<std::string>
        _file_name; // 文件消息的文件名称 -- 只针对文件消息有效

    odb::nullable<unsigned int>
        _file_size; // 文件消息的文件大小 -- 只针对文件消息有效
};
// odb -d mysql --std c++11 --generate-query --generate-schema --profile
// boost/date-time person.hxx
} // namespace ken_im